package com.example.shirodemo.authentication;

import com.example.shirodemo.entities.Permission;
import com.example.shirodemo.entities.Role;
import com.example.shirodemo.entities.User;
import com.example.shirodemo.services.IPermissionService;
import com.example.shirodemo.services.IRoleService;
import com.example.shirodemo.services.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class DBShiroRealm extends AuthorizingRealm {

    @Autowired
    IUserService userService;
    @Autowired
    IRoleService roleService;
    @Autowired
    IPermissionService permissionService;

    /**
     * 一定要重写support()方法，在后面的身份验证器中会用到
     *
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 授权模块，获取用户角色和权限
     *
     * @param principal
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        // 这个realm不进行授权
        return new SimpleAuthorizationInfo();
    }

    /**
     * 用户认证
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取用户输入的用户名和密码
        String userName = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        User user = userService.findByName(userName);

        if (user == null)
            throw new UnknownAccountException("用户名或密码错误！");
        if (!StringUtils.equals(password, user.getPassword()))
            throw new IncorrectCredentialsException("用户名或密码错误！");
        if (User.STATUS_LOCK == user.getStatus())
            throw new LockedAccountException("账号已被锁定,请联系管理员！");

        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }
}
